package com.sx.pay.service.alipay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.sx.pay.model.AlipayParams;
import com.sx.pay.model.PayModel;
import com.sx.pay.model.PayType;
import com.sx.pay.model.RefundModel;
import com.sx.pay.service.AbsPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * @author AdinZ
 * @date 2020/8/28 16:14
 */
public class AliPayService extends AbsPayService {
    private final DefaultAlipayClient alipayClient;
    private final String charset="utf8";
    private final AlipayParams params;
    private Logger log= LoggerFactory.getLogger(this.getClass());

    public AliPayService(AlipayParams params){
        super(params);
        this.params=params;
        this.alipayClient = new DefaultAlipayClient(
                params.getServerUrl(),
                params.getAppId(),
                params.getPrivateKey(),
                "json",
                charset,
                params.getAlipayPublicKey(),
                "RSA2"
        );
    }

    @Override
    public Map createPayOrder(PayModel payModel) {

        final String totalAmount=payModel.getPayMoney().setScale(2, RoundingMode.HALF_EVEN).toPlainString();
        try {
            AlipayResponse response;
            if(payModel.getPayType()== PayType.ALIPAY_APP) {
                AlipayTradeAppPayModel model=new AlipayTradeAppPayModel();
                model.setOutTradeNo(payModel.getPayCode());
                model.setTotalAmount(totalAmount);
//                model.setProductCode("QUICK_MSECURITY_PAY");
                model.setSubject(payModel.getTitle());
                response = this.createAppPay(model);
            }else if(payModel.getPayType()==PayType.ALIPAY_PC) {
                AlipayTradePagePayModel model =new AlipayTradePagePayModel();
                model.setOutTradeNo(payModel.getPayCode());
                model.setTotalAmount(totalAmount);
                model.setProductCode("FAST_INSTANT_TRADE_PAY");
                model.setSubject(payModel.getTitle());
                response = this.createPcPay(model);
            }else if(payModel.getPayType()==PayType.ALIPAY_WAP) {
                AlipayTradeWapPayModel model =new AlipayTradeWapPayModel();
                model.setOutTradeNo(payModel.getPayCode());
                model.setTotalAmount(totalAmount);
                model.setProductCode("QUICK_WAP_WAY");
                model.setQuitUrl(this.returnUrl);
                model.setSubject(payModel.getTitle());
                response = this.createWapPay(model);
            }else throw new RuntimeException("类型有误");
            if (response.isSuccess()) {
                log.info("[支付宝支付] 接口返回支付参数\t\t  {} \r\n 请求参数:{}",response.getBody(),payModel.toString());
                Map<String, Object> map = new HashMap<>();
                map.put("body", response.getBody());
                return map;
            } else {
                throw new RuntimeException("获取支付参数失败");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

    @Override
    public boolean verify(JSONObject data) {
        Map<String,String> params=new HashMap<>();
        for(String key:data.keySet()){
            params.put(key,data.getString(key));
        }
        try {
            boolean checkV1 = AlipaySignature.rsaCheckV1(params, this.params.getAlipayPublicKey(), charset, "RSA2");
            log.info("[支付服务] 支付宝支付-验证回调签名{}   全部参数:{}",checkV1,data);
            return checkV1;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return false;
    }
    private AlipayResponse createWapPay(AlipayTradeWapPayModel model) throws AlipayApiException {
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setNotifyUrl(super.getNotifyUrl());
        if(StringUtils.isEmpty(super.getReturnUrl()))
            request.setReturnUrl(super.getReturnUrl());
        request.setBizModel(model);
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
        return response;
    }
    private AlipayResponse createPcPay(AlipayTradePagePayModel model) throws AlipayApiException {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(super.getNotifyUrl());
        if(StringUtils.isEmpty(super.getReturnUrl()))
            request.setReturnUrl(super.getReturnUrl());
        request.setBizModel(model);
        AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
        return response;
    }
    private AlipayResponse createAppPay(AlipayTradeAppPayModel model) throws AlipayApiException {
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        request.setNotifyUrl(super.getNotifyUrl());
        if(StringUtils.isEmpty(super.getReturnUrl()))
            request.setReturnUrl(super.getReturnUrl());
        request.setBizModel(model);
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        return response;
    }

    @Override
    public String getAppId() {
        return params.getAppId();
    }

    @Override
    public void refund(RefundModel model) {
        AlipayTradeRefundRequest request=new AlipayTradeRefundRequest();
        AlipayTradeRefundModel requestModel=new AlipayTradeRefundModel();
        if(!StringUtils.isEmpty(model.getPayCode()))
            requestModel.setOutTradeNo(model.getPayCode());
        if(!StringUtils.isEmpty(model.getTransCode()))
            requestModel.setTradeNo(model.getTransCode());
        requestModel.setRefundAmount(model.getRefundFee().setScale(2,RoundingMode.HALF_EVEN).toPlainString());
        request.setBizModel(requestModel);

        try {
            AlipayTradeRefundResponse response=alipayClient.execute(request);
            log.info("[支付宝退款接口] 接口请求返回数据{}   请求数据{}",JSON.toJSONString(response),model);
            if(!response.isSuccess())
                throw new RuntimeException(response.getBody());
        } catch (AlipayApiException e) {
            log.error("[支付宝退款接口] 接口请求异常{}",model,e);
           throw new RuntimeException(e);
        }
    }




}
